package com.mojo.openapi.controller;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.*;

public class ApiSignatureUtils {

    // 生成签名
    public static String generateSignature(Map<String, String> params, String appSecret) {
        // 将参数名按照字典序排序
        List<String> paramList = new ArrayList<>(params.keySet());
        Collections.sort(paramList);

        // 拼接参数名与参数值
        StringBuilder sb = new StringBuilder();
        for (String key : paramList) {
            sb.append(key).append("=").append(params.get(key)).append("&");
        }
        sb.append("appSecret=").append(appSecret);

        // 计算MD5哈希值作为签名
        String toSign = sb.toString();
        return md5(toSign);
    }

    // 验证签名
    public static boolean verifySignature(Map<String, String> params, String appSecret, String signature) {
        String generatedSignature = generateSignature(params, appSecret);
        System.out.println("校验签名：" + generatedSignature);
        return generatedSignature.equals(signature);
    }

    // 计算MD5哈希值
    private static String md5(String input) {
        try {
            MessageDigest md = MessageDigest.getInstance("SHA-256");
            byte[] messageDigest = md.digest(input.getBytes());
            return bytesToHex(messageDigest);
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException("MD5 algorithm not found");
        }
    }

    // 将字节数组转换为十六进制字符串表示
    private static String bytesToHex(byte[] bytes) {
        StringBuilder result = new StringBuilder();
        for (byte b : bytes) {
            result.append(String.format("%02x", b));
        }
        return result.toString();
    }

    public static void main(String[] args) {
        // 假设这是接口请求参数
        Map<String, String> params = new HashMap<>();
        params.put("appId", "your_app_id");
        params.put("timestamp", String.valueOf(System.currentTimeMillis() / 1000)); // 时间戳
        params.put("param1", "value1");
        params.put("param2", "value2");

        String appSecret = "your_app_secret";

        // 在请求中添加签名
        String signature = generateSignature(params, appSecret);
        System.out.println("请求签名：" + signature);
        params.put("signature", signature);

        // 发送请求，并在接收端验证签名
        // 验证签名
        String receivedSignature = params.get("signature");
        params.remove("signature"); // 从参数中删除签名字段
        if (verifySignature(params, appSecret, receivedSignature)) {
            System.out.println("签名验证通过");
        } else {
            System.out.println("签名验证失败");
        }
    }
}
